/*
 * helper_thread.h
 *
 *  Created on: Nov 25, 2011
 *      Author: bendischinger
 */

#ifndef HELPER_THREAD_H_
#define HELPER_THREAD_H_

/**
 * Helper thread code
 */
#ifdef __MAIN
#define __EXTERN
#else
#define __EXTERN extern
#endif

#define	DEFAULT_HWM 200
#define DEFAULT_LWM 100
#define WM_INCR 20

__EXTERN pthread_mutex_t ht_sync;
__EXTERN pthread_cond_t ht_wake;
__EXTERN int ht_active;
__EXTERN int ht_worker_i;
__EXTERN int ht_helper_i;
__EXTERN int ht_behind;
__EXTERN int ht_hwm;
__EXTERN int ht_lwm;

#undef __EXTERN

#define HT_INIT() \
	pthread_mutex_init(&ht_sync, NULL);\
	pthread_cond_init(&ht_wake, NULL);\
	ht_worker_i = 0;\
	ht_helper_i = 0;\
	ht_behind = 0;\
	ht_hwm = DEFAULT_HWM;\
	ht_lwm = DEFAULT_LWM;\
	ht_active = 1

#define WORKER_SYNC() \
	if (ht_active) {\
		pthread_mutex_lock(&ht_sync);\
		if (ht_helper_i < ht_worker_i + ht_lwm) {\
			pthread_cond_signal(&ht_wake);\
		}\
		ht_worker_i++;\
	}\
	if (ht_active) pthread_mutex_unlock(&ht_sync)

#define HELPER_SYNC() \
	pthread_mutex_lock(&ht_sync);\
	if (ht_helper_i > ht_worker_i + ht_hwm) {\
		global_stat.helper_ahead_cnt++;\
		pthread_cond_wait(&ht_wake, &ht_sync);\
	}\
	if (!ht_behind && ht_helper_i < ht_worker_i) {\
		global_stat.helper_behind_cnt++;\
		ht_behind = 1;\
	}\
	if (ht_behind && ht_helper_i > ht_worker_i + ht_lwm) {\
		ht_behind = 0;\
	}\
	ht_helper_i++;\
	pthread_mutex_unlock(&ht_sync);\
	if (ht_behind) continue

/* END Helper Thread Variables */

#endif /* HELPER_THREAD_H_ */
